package com.snb.play.dwebtoon.data;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;

import com.snb.play.dwebtoon.util.DBProvider;
import com.snb.play.dwebtoon.util.Logger;

public abstract class JSonDataObjectBase implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1000L;
	// 디버그 용
	// boolean isDebug = true;
	static boolean isDebug = false;

	// DB완성 되면 사용
	// boolean isNotComplte = true;
	boolean isNotComplte = false;

	// final String BASEINSERT =
	// "INSERT INTO _TABLE_ ( _NAMES_ ) VALUES ( _VALUE_ )";INSERT OR IGNORE INTO tbl_breed (breed_breed)"+" VALUES ('Test')"
	final String BASEINSERT = "INSERT OR IGNORE INTO _TABLE_ ( _NAMES_ ) VALUES ( _VALUE_ )";
	final String BASEINSERORUPDATE = "INSERT OR REPLACE INTO _TABLE_ ( _NAMES_ , id) VALUES ( _VALUE_ , (select id from _TABLE_ where id = _ID_) );";
//	final String BASEINSERT = "INSERT OR REPLACE INTO _TABLE_ ( _NAMES_ , id) VALUES ( _VALUE_ , (select id from _TABLE_ where id = _ID_) );";
	final String BASEUPDATE = "UPDATE _TABLE_ SET _KEYVALUE_ WHERE id='_ID_';";
	final String BASEDELETE = "DELETE  FROM _TABLE_ WHERE id LIKE _ID_;";

	public String TAG = getClass().getSimpleName();

	public void init(JSONObject aJsonObject) {
		@SuppressWarnings("unchecked")
		Iterator<Object> iterator = aJsonObject.keys();
		while (iterator.hasNext()) {
			Object obj = iterator.next();
			setMemberFiled(this, aJsonObject, obj.toString());
		}
	}

	public static void setMemberFiled(Object aTarGetObject, JSONObject aJsonObject, String aFieldName) {
		Field f;
		try {

			f = aTarGetObject.getClass().getField(aFieldName);
			if (f != null) {
				f.set(aTarGetObject, aJsonObject.getString(aFieldName));
			}
		} catch (NoSuchFieldException e) {
			if (isDebug)
				e.printStackTrace();
		} catch (IllegalArgumentException e) {
			if (isDebug)
				e.printStackTrace();
		} catch (IllegalAccessException e) {
			if (isDebug)
				e.printStackTrace();
		} catch (JSONException e) {
			if (isDebug)
				e.printStackTrace();
		}

	}

	public Map<String, Object> getKeyValueAllMemebers() throws NoSuchFieldException {
		Map<String, Object> params = new HashMap<String, Object>();
		Field[] f = this.getClass().getDeclaredFields();
		for (Field lCF : f) {
			try {
				if (lCF.getType().getSimpleName().equalsIgnoreCase(String.class.getSimpleName())) {
					if (lCF.get(this) != null && !lCF.getName().equalsIgnoreCase("TAG")) {
						Logger.d(TAG, lCF.getName() + " = = = " + lCF.get(this).toString());
						params.put(lCF.getName(), lCF.get(this).toString());
					}
				} else {

					Field lChiledF[] = lCF.getType().getDeclaredFields();
					for (Field ff : lChiledF) {
						Logger.d(TAG, "ff > " + ff.getName());
						if (ff.getName().startsWith("id")) {
							if (lCF.get(this) != null && ff.get(lCF.get(this)) != null) {
								Logger.d(TAG, "ff.get(lCF.get(this)).toString() > " + ff.get(lCF.get(this)).toString());
								params.put(lCF.getName(), ff.get(lCF.get(this)).toString());
							}
						}
					}

				}
			} catch (IllegalAccessException e) {
				if (isDebug)
					e.printStackTrace();
			}
		}

		return params;
	}

	/**
	 * @return DB에 자동으로 값을 넣거나 업데이트 할때 써벅으려궁
	 */
	public String getAllMemeberValues() {
		StringBuilder names = new StringBuilder();
		StringBuilder values = new StringBuilder();
		Field[] f = this.getClass().getDeclaredFields();
		for (Field lCF : f) {

			try {
				if (lCF.getType().getSimpleName().equalsIgnoreCase(String.class.getSimpleName())) {
					if (lCF.get(this) != null && !lCF.getName().equalsIgnoreCase("TAG")) {
						values.append(",");
						names.append(",");
						values.append("'" + lCF.get(this).toString().replace("\"", "*").replace("'", "#").replace(",", "%") + "'");
						names.append(lCF.getName());
					}
				} else if (lCF.getType().getSimpleName().equalsIgnoreCase(ArrayList.class.getSimpleName())) {

					if (lCF.get(this) != null) {
						Logger.d(TAG, "ARRAYLIST어쩌찡?");
						@SuppressWarnings("unchecked")
						ArrayList<Object> lObList = (ArrayList<Object>) lCF.get(this);
						if (lObList != null && lObList.size() > 0) {
							values.append(",");
							names.append(",");
							names.append(lCF.getName());
							for (int i = 0; i < lObList.size(); i++) {
								Field lChiledF[] = lObList.get(i).getClass().getDeclaredFields();
								for (Field ff : lChiledF) {
									if (ff.getName().startsWith("id") && lObList.get(i) != null && ff.get(lObList.get(i)) != null) {
										if (i == 0)
											values.append("'");

										if (i > 0) {
											values.append("//");
										}
										values.append(ff.get(lObList.get(i)).toString().replace("\"", "*").replace("'", "#").replace(",", "%"));
										if (lObList.size() - 1 == i)
											values.append("'");

										break;
									}
								}
							}
						}
					}
				} else if (lCF.getType().getName().startsWith("com.snb")) {
					Field lChiledF[] = lCF.getType().getDeclaredFields();
					for (Field ff : lChiledF) {
						if (ff.getName().startsWith("id") && lCF.get(this) != null && ff.get(lCF.get(this)) != null) {
							values.append(",");
							names.append(",");
							values.append("'" + ff.get(lCF.get(this)).toString().replace("\"", "*").replace("'", "#").replace(",", "%") + "'");
							names.append(lCF.getName());
							break;
						}
					}
				}
			} catch (IllegalAccessException e) {
				if (isDebug)
					e.printStackTrace();
			}
		}

		return values.toString().substring(1) + "11AA11" + names.toString().substring(1);
	}

	public String getAllMemeberValuesNonId() {
		StringBuilder names = new StringBuilder();
		StringBuilder values = new StringBuilder();
		Field[] f = this.getClass().getDeclaredFields();
		for (Field lCF : f) {

			try {
				if (lCF.getType().getSimpleName().equalsIgnoreCase(String.class.getSimpleName())) {
					if (lCF.get(this) != null && !lCF.getName().equalsIgnoreCase("TAG") && !lCF.getName().equalsIgnoreCase("id")) {
						values.append(",");
						names.append(",");
						values.append("'" + lCF.get(this).toString().replace("\"", "*").replace("'", "#").replace(",", "%") + "'");
						names.append(lCF.getName());
					}
				} else if (lCF.getType().getSimpleName().equalsIgnoreCase(ArrayList.class.getSimpleName())) {

					if (lCF.get(this) != null) {
						Logger.d(TAG, "ARRAYLIST어쩌찡?");
						@SuppressWarnings("unchecked")
						ArrayList<Object> lObList = (ArrayList<Object>) lCF.get(this);
						if (lObList != null && lObList.size() > 0) {
							values.append(",");
							names.append(",");
							names.append(lCF.getName());
							for (int i = 0; i < lObList.size(); i++) {
								Field lChiledF[] = lObList.get(i).getClass().getDeclaredFields();
								for (Field ff : lChiledF) {
									if (ff.getName().startsWith("id") && lObList.get(i) != null && ff.get(lObList.get(i)) != null) {
										if (i == 0)
											values.append("'");

										if (i > 0) {
											values.append("//");
										}
										values.append(ff.get(lObList.get(i)).toString().replace("\"", "*").replace("'", "#").replace(",", "%"));
										if (lObList.size() - 1 == i)
											values.append("'");

										break;
									}
								}
							}
						}
					}
				} else if (lCF.getType().getName().startsWith("com.snb")) {
					Field lChiledF[] = lCF.getType().getDeclaredFields();
					for (Field ff : lChiledF) {
						if (ff.getName().startsWith("id") && lCF.get(this) != null && ff.get(lCF.get(this)) != null) {
							values.append(",");
							names.append(",");
							values.append("'" + ff.get(lCF.get(this)).toString().replace("\"", "*").replace("'", "#").replace(",", "%") + "'");
							names.append(lCF.getName());
							break;
						}
					}
				}
			} catch (IllegalAccessException e) {
				if (isDebug)
					e.printStackTrace();
			}
		}

		return values.toString().substring(1) + "11AA11" + names.toString().substring(1);
	}

	public void insertObjToDB() {
		if (isNotComplte)
			return;
		// 방식이 넘 허접하다 뭔가 다른걸 찾아봐야함 -_-;
		// upsertObjToDB();
		String[] lKeyValue = getAllMemeberValues().split("11AA11");
		String lValues = "";
		String lNames = "";
		if (lKeyValue[0].trim().lastIndexOf(",") > lKeyValue[0].trim().length() - 1)
			lValues = lKeyValue[0].trim().substring(0, lKeyValue[0].trim().length() - 1);
		else
			lValues = lKeyValue[0].trim();

		if (lKeyValue[1].trim().lastIndexOf(",") > lKeyValue[1].trim().length() - 1)
			lNames = lKeyValue[1].trim().substring(0, lKeyValue[1].trim().length() - 1);
		else
			lNames = lKeyValue[1].trim();

		int result;
		try {
			result = DBProvider.getInstance().executeDirectSqlNonClose(
					BASEINSERT.replace(DBProvider._TABLE, this.getClass().getSimpleName()).replace(DBProvider._NAMES, lNames)
							.replace(DBProvider._VALUE, lValues).replace(DBProvider._ID, this.getClass().getField("id").get(this).toString()));
			Logger.d(TAG, result + "");
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public String getSqlForInsertObjToDB() {
		String[] lKeyValue = getAllMemeberValues().split("11AA11");
		String lValues = "";
		String lNames = "";
		if (lKeyValue[0].trim().lastIndexOf(",") > lKeyValue[0].trim().length() - 1)
			lValues = lKeyValue[0].trim().substring(0, lKeyValue[0].trim().length() - 1);
		else
			lValues = lKeyValue[0].trim();

		if (lKeyValue[1].trim().lastIndexOf(",") > lKeyValue[1].trim().length() - 1)
			lNames = lKeyValue[1].trim().substring(0, lKeyValue[1].trim().length() - 1);
		else
			lNames = lKeyValue[1].trim();

		try {
			return BASEINSERT.replace(DBProvider._TABLE, this.getClass().getSimpleName()).replace(DBProvider._NAMES, lNames)
					.replace(DBProvider._VALUE, lValues).replace(DBProvider._ID, this.getClass().getField("id").get(this).toString());
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;

	}
	
	public void updateTouch(Context aCtx, Map<String, Object> aMap) {
		if (isNotComplte)
			return;
		boolean isHaveId = false;
		String lID = "";
		StringBuilder lKeyValue = new StringBuilder();
		int result = 0;

		Iterator<String> lKeys = aMap.keySet().iterator();

		if (lKeys.hasNext()) {
			String lKey = lKeys.next();
			lKeyValue.append(lKey);
			lKeyValue.append("=");
			lKeyValue.append("'" + aMap.get(lKey).toString() + "'");
		}

		while (lKeys.hasNext()) {
			String lKey = lKeys.next();
			lKeyValue.append(", ");
			lKeyValue.append(lKey);
			lKeyValue.append("=");
			lKeyValue.append("'" + aMap.get(lKey).toString() + "'");
		}

		try {
			lID = this.getClass().getField("id").get(this).toString();
			isHaveId = true;
		} catch (Exception e) {
			isHaveId = false;
		}

		Logger.d(
				TAG,
				BASEUPDATE.replace(DBProvider._TABLE, this.getClass().getSimpleName()).replace(DBProvider._KEYVALUE, lKeyValue)
						.replace(DBProvider._ID, lID));
		if (isHaveId) {
			result = DBProvider.getInstance().executeDirectSqlNonClose(
					BASEUPDATE.replace(DBProvider._TABLE, this.getClass().getSimpleName()).replace(DBProvider._KEYVALUE, lKeyValue)
							.replace(DBProvider._ID, lID.trim()));
		}
		Logger.d(TAG, "DBUPDATE == " + result);
	}

	public void upsertObjToDB() {
		if (isNotComplte)
			return;
		// 방식이 넘 허접하다 뭔가 다른걸 찾아봐야함 -_-;
		boolean isHaveId = false;
		String lID = "";
		String[] lKeyValue = null;
		int result = 0;
		try {
			lID = (this.getClass().getField("id")).get(this).toString();
		} catch (Exception e) {
		}
		if (lID.length() > 0) {
			lKeyValue = getAllMemeberValuesNonId().split("11AA11");
			isHaveId = true;
		} else
			lKeyValue = getAllMemeberValues().split("11AA11");

		String lValues = "";
		String lNames = "";
		if (lKeyValue[0].trim().lastIndexOf(",") > lKeyValue[0].trim().length() - 1)
			lValues = lKeyValue[0].trim().substring(0, lKeyValue[0].trim().length() - 1);
		else
			lValues = lKeyValue[0].trim();

		if (lKeyValue[1].trim().lastIndexOf(",") > lKeyValue[1].trim().length() - 1)
			lNames = lKeyValue[1].trim().substring(0, lKeyValue[1].trim().length() - 1);
		else
			lNames = lKeyValue[1].trim();

		if (isHaveId)
			result = DBProvider.getInstance().executeDirectSqlNonClose(
					BASEINSERORUPDATE.replace(DBProvider._TABLE, this.getClass().getSimpleName()).replace(DBProvider._NAMES, lNames)
							.replace(DBProvider._VALUE, lValues).replace(DBProvider._ID, lID));
		else
			result = DBProvider.getInstance().executeDirectSqlNonClose(
					BASEINSERT.replace(DBProvider._TABLE, this.getClass().getSimpleName()).replace(DBProvider._NAMES, lNames)
							.replace(DBProvider._VALUE, lValues));
	}

	public void printMembers() {
		if (!isDebug)
			return;

		try {
			Field[] f = this.getClass().getDeclaredFields();
			for (Field lCF : f) {
				try {
					Logger.d(TAG, lCF.getName() + " === ");
					if (lCF.getType().getSimpleName().equalsIgnoreCase(String.class.getSimpleName()))
						if (lCF.get(this) != null)
							Logger.d(TAG, lCF.getName() + " = = = " + lCF.get(this).toString());
				} catch (IllegalAccessException e) {
					if (isDebug)
						e.printStackTrace();
				}
			}
		} catch (IllegalArgumentException e) {
			if (isDebug)
				e.printStackTrace();
		}
	}
}
